#include <crf_sequence/data.h>
#include "st_wrapper.h"

#include <sstream>
#include <boost/shared_ptr.hpp>

EventPtr convert_event(CliqueDetector::EventPtr in, int num_features)
{
	NodeDetector::ChartPtr chart = in->node_chart;	
	int len = in->length;
	int order = chart->order;
	EventPtr crf_event(new Event(order, (size_t)len));
	SparseArrayPtr sa;

    // read the node features
    for(int i=0; i < len; ++i)
	{
		for(int o=0; i-o >=0 && o < order; ++o)
		{
			NodePtr n(new Node);

			// copy the features
			for (size_t j=0; j<chart->features[i][o]->nodes.size(); ++j)
			{
				NodeDetector::NodeFeaturesPtr node_features 
					= chart->features[i][o]->nodes[j];
				sa = SparseArrayPtr(new SparseArray(num_features));
				// BUG? does the map not being sorted matter here?
				for (NodeDetector::FeatureSet::const_iterator it
					 = node_features->features.begin();
					 it != node_features->features.end(); ++it)
					sa->insert(it->first, it->second);
				n->features.push_back(sa);
	
				if (node_features->gold)
					n->gold = j; 
			}
			// add the new node
			crf_event->nodes[o][i-o] = n;
		}
	}

    // read the clique features
    for(int i=0; i < len-1; ++i)
	{
		size_t first_num_labels = chart->features[i][0]->nodes.size();
		size_t second_num_labels = chart->features[i+1][0]->nodes.size();
		if (order>1) assert(first_num_labels==second_num_labels);
//		std::cerr << first_num_labels << " " << second_num_labels << std::endl;
		for(int o=0; i-o >= 0 && o < order; ++o)
		{

			BaseCliquePtr c(new Clique(first_num_labels, second_num_labels));

			// copy the features
//			for (size_t j=0; j<in->cliques[i][o]->labellings.size(); ++j)
			size_t j=0;
			for (size_t b=0; b<second_num_labels; ++b)
				for (size_t a=0; a<first_num_labels; ++a)
				{
					NodeDetector::FeatureSetPtr features 
						= in->cliques[i][o]->labellings[j];
					sa = SparseArrayPtr(new SparseArray(num_features));
					// BUG? does the map not being sorted matter here?
					for (NodeDetector::FeatureSet::const_iterator it = features->begin();
						 it != features->end(); ++it)
						sa->insert(it->first, it->second);
					c->labelling(sa,a*second_num_labels+b);
	//				std::cerr << j << " " << in->cliques[i][o]->labellings.size() << std::endl;
					j++;
				}

			// add the new clique
			crf_event->cliques[o][i-o] = c;
		}
	}
	return crf_event;
}
